Rem
Encryption/decryption helper module for mscchat

Copyright (c) 2009 Michael Schaefer and Immo-Gert Birn

Mscchat is free software: you can redistribute it And/Or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, Or
(at your option) any later version.

Mscchat is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY Or FITNESS For A PARTICULAR PURPOSE.  See the
GNU General Public License For more details.

You should have received a copy of the GNU General Public License
along with mscchat.  If Not, see <http://www.gnu.org/licenses/>.
EndRem

' Nutzer brauchen die Anweisung:
' Import  BaH.Base64

Type TIgbCrypt
  Field _key:String

  Method Create:TIgbCrypt(key:String)
    Self._key = key
    Return Self
  EndMethod

  ' verschlusseltes + base64 encodiertes Ergebnis
  Method encode:String(in:String)
     Local encr:String = _rc4(in)
     Return TBase64.Encode( encr , encr.length )
  EndMethod

  Method decode:String(in:String)
     Local data:Byte[] = TBase64.Decode(in)
     Local decoded:String = String.FromBytes(data, data.length)
     Return _rc4(decoded)
  EndMethod

	'----------------------------------------------------------------------------
	' Symmetrische RC4-Verschluesselung
	'----------------------------------------------------------------------------
	' see http://en.wikipedia.org/wiki/RC4
	'----------------------------------------------------------------------------
	' Parameter:
	'   inp: Verschluesseln: der zu verschluesselnde Text
	'        Entschluesseln: er zu entschluesselnde Text
	'   key: das Passwort
	' Beispielprogramm:
	'   SuperStrict
	'   Local pass:String = "adjkloefdscfgl" 
	'   Local msg:String  = "Test"
	'   Local res:String =  RC4(msg, pass)
	'   Print "Crypt  : " + res
	'   Print "Decrypt: " + RC4(res,pass)
	'----------------------------------------------------------------------------
	Method _rc4:String(inp:String)
	    Local S:Int[512+Ceil(inp.Length*.55)]
	    Local i:Int, j:Int, t:Int, x:Int
	    Local outbuf:Short Ptr = Short Ptr(Varptr s[512])
	    
	    j = 0
	    For i = 0 To 255
	        S[i] = i
	        If j > (_Key.length-1) Then
	            j = 0
	        EndIf
	        S[256+i] = _key[j]&$ff
	        j:+ 1
	    Next
	    
	    j = 0
	    For i = 0 To 255
	        j = (j + S[i] + S[256+i]) & $ff
	        t = S[i]
	        S[i] = S[j]
	        S[j] = t
	    Next
	    
	    i = 0
	    j = 0
	    For Local x% = 0 To inp.Length-1
	        i = (i + 1) & $ff
	        j = (j + S[i]) & $ff
	        t = S[i]
	        S[i] = S[j]
	        S[j] = t
	        t = (S[i] + S[j]) & $ff
	        outbuf[x] = (inp[x] ~ S[t])
	    Next
	    
	    Return String.FromShorts(outbuf, inp.Length)
	EndMethod

EndType 